package com.open4cn.simulator.device;

import com.open4cn.simulator.core.answer.AbstractAnswer;
import com.open4cn.simulator.core.answer.AnswerModeEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author yinxiaopeng
 * @version 1.0.0
 * @company 致景科技
 * @department 飞梭BU/研发
 * @description
 * @Email yinxiaopeng@zj.tech
 * @date 2022-05-15 01:33
 */
public class AnswerManager {
    private static Logger logger = LoggerFactory.getLogger(AnswerManager.class);

    // k= 设备唯一标识
    private ConcurrentHashMap<String, Map<String, AbstractAnswer>> answerContainer = new ConcurrentHashMap<>();


    /**
     * 获取指定设备下的单个应答器
     *
     * @param deviceId
     * @param scene
     * @return
     */
    public AbstractAnswer getSingle(String deviceId, String scene) {
        if (null == deviceId || null == scene) {
            return null;
        }
        Map<String, AbstractAnswer> map = answerContainer.get(deviceId);
        if (null == map || map.isEmpty()) {
            return null;
        }
        return map.get(scene);
    }

    /**
     * 获取指定设备下的全部应答器
     *
     * @param deviceId
     * @return
     */
    public List<AbstractAnswer> getMulti(String deviceId) {
        if (null == deviceId) {
            return new ArrayList<>();
        }
        Map<String, AbstractAnswer> map = answerContainer.get(deviceId);
        if (null == map || map.isEmpty()) {
            return new ArrayList<>();
        }
        return new ArrayList<>(map.values());
    }


    public boolean exists(String deviceId) {
        if (null == deviceId) {
            return false;
        }
        return answerContainer.containsKey(deviceId);
    }


    /**
     * 存储
     *
     * @param deviceId
     * @param answers
     */
    public void put(String deviceId, List<AbstractAnswer> answers) {
        if ((null == deviceId
                || null == answers || answers.isEmpty())) {
            return;
        }
        Map<String, AbstractAnswer> map = answerContainer.get(deviceId);
        if (null == map) {
            map = new HashMap<>();
        }
        for (AbstractAnswer answer : answers) {
            map.put(answer.getScene(), answer);
        }
        answerContainer.put(deviceId, map);
    }


    /**
     * 获取指定设备下的单个应答器的快照
     *
     * @param deviceId
     * @param scene
     * @return
     */
    public String getSingleSnapshot(String deviceId, String scene) {
        AbstractAnswer answer = getSingle(deviceId, scene);
        if (null == answer) {
            return null;
        }
        StringBuilder builder = new StringBuilder();
        builder.append(answer.getScene())
                .append(":")
                .append(answer.getAnswerMode().name())
                .append("loop(")
                .append(null != answer.getLoop())
                .append("):queue(")
                .append(null != answer.getInputQueue() ? answer.getInputQueue().size() : 0)
                .append(")");
        return builder.toString();
    }


    /**
     * 获取指定设备下的全部应答器的快照
     *
     * @param deviceId
     * @return
     */
    public List<String> getMultiSnapshot(String deviceId) {
        List<AbstractAnswer> answers = getMulti(deviceId);
        List<String> snapshot = new ArrayList<>();
        answers.forEach(answer -> {
            StringBuilder builder = new StringBuilder();
            builder.append(answer.getScene())
                    .append(":")
                    .append(answer.getAnswerMode().name())
                    .append("loop(")
                    .append(null != answer.getLoop())
                    .append("):queue(")
                    .append(null != answer.getInputQueue() ? answer.getInputQueue().size() : 0)
                    .append(")");

            snapshot.add(builder.toString());
        });
        return snapshot;
    }


    /**
     * 改变应答模式以及应答值
     *
     * @param deviceId
     * @param scene
     * @param answerModeName
     * @param values         可为null
     */
    public void changeAnswerMode(String deviceId, String scene, String answerModeName, List<Object> values) {
        AbstractAnswer answer = getSingle(deviceId, scene);
        if (null != answer) {
            AnswerModeEnum answerModeEnum = AnswerModeEnum.valueOf(answerModeName);
            if (null != answerModeEnum) {
                answer.setAnswerMode(answerModeEnum);
            }

            if (null != values && !values.isEmpty()) {
                answer.changeAnswerValue(values);
            }
        }
    }


    /**
     * --------------------------------------------
     **/

    private AnswerManager() {
    }

    private static class HolderClass {
        private static final AnswerManager instance = new AnswerManager();
    }

    public static AnswerManager getInstance() {
        return AnswerManager.HolderClass.instance;
    }
}
